import { ModuleC, ModuleS, SoundManager } from "odin";
import { Consts } from "../../Consts";
import { CoinData } from "./CoinData";

/**
 * @Author: zhaolei
 * @Date: 2022-08-01 09:41:04
 * @LastEditors: zhaolei
 * @Description: 金币模块
 * 服务端-负责增加金币
 * 客户端-负责判断玩家接触金币，播放金币动画
 */
export class CoinModuleS extends ModuleS<CoinModuleC, CoinData>{
	public override onAwake(): void {
	}

	/**
	 * 吃掉金币,一般net_开头的函数代表提供给远端调用
	 * currentData-表示是调用该方法的客户端的玩家数据中心
	 */
	public net_Eat(position: Type.Vector) {
		this.currentData.addCount(1);
		this.currentData.saveData(true);
		// 所有客户端都会听到吃金币的音效，所以在服务端调用，odin提供的方法会广播给所有客户端
		SoundManager.instance.play3DSound(Consts.EAT_COIN_SOUND, position, 1);
	}
}
export class CoinModuleC extends ModuleC<CoinModuleS, CoinData>{

	/**
	 * 金币实例
	 */
	private _coins: MWCore.GameObject[];
	/**
	 * 金币旋转
	 */
	private _coinRotation: Type.Rotation;

	public override onAwake(): void {
		this._coins = [];
		Consts.COIN_GUIDS.forEach(guid => {
			this._coins.push(MWCore.GameObject.find(guid));
		});

		// 获取所有金币，绑定玩家进入后的事件
		for (const coin of this._coins) {
			// 获取金币中的触发器
			const trigger = coin.getChildren()[0] as GamePlay.Trigger;
			trigger.onEnter.add((gameObject) => {
				if (GamePlay.isCharacter(gameObject)) {
					const playerId = (gameObject as GamePlay.Character).player.getPlayerID();
					// 如果触碰到金币的是自己，则增加金币，同时删除地图上的这个金币物体（不用处理其他端的金币，每个客户端都会走这个逻辑）
					if (playerId == this.currentPlayerId) {
						const coinIndex = this._coins.indexOf(coin);
						this.server.net_Eat(coin.location);
						this._coins.splice(coinIndex, 1);
						coin.destroy();
					}
				}
			});
		}
		this._coinRotation = new Type.Rotation();
	}

	/**
	 * 更新所有金币的旋转
	 * @param dt 
	 */
	override onUpdate(dt: number): void {
		this._coinRotation.z += dt * 100;
		for (const coin of this._coins) {
			coin.rotation = this._coinRotation;
		}
	}
}